package com.vanhung.speedtest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.os.Environment;
import android.util.Log;
import android.view.View;

public class AsyncDownloader extends AsyncNetWorker {

	private static final String TAG = AsyncDownloader.class.getSimpleName();

	public AsyncDownloader(SpeedTestLauncher activity) {
		super(activity);
	}

	@Override
	protected void onPreExecute() {
		mTxtUploadSpeed.setText("");

		btnStart.setText(R.string.mainbtn_down);
		btnStart.setEnabled(false);
		//btnCancel.setEnabled(true);
		btnCancel.setVisibility(View.VISIBLE);
		updateProgress(0, 0);
	}

	@Override
	protected Double doInBackground(String... urls) {
		long bytesIn = 0;
		long downloadTime = 1;
		InputStream stream = null;

		try {
			URL url = new URL(urls[0]);
			URLConnection con = url.openConnection();
			con.setUseCaches(false);
			stream = con.getInputStream();

			long start = System.currentTimeMillis();
			long updateStart = System.currentTimeMillis();
			long updateDelta = 0;
			int bytesInThreshold = 0;

			File SDCardRoot = Environment.getExternalStorageDirectory();
			File file = new File(SDCardRoot, FILE_NAME);
			// this will be used to write the downloaded data into the file we created
			FileOutputStream fileOutput = new FileOutputStream(file);

			byte[] buffer = new byte[1];
			int bufferLength = 0;

			while ((bufferLength = stream.read(buffer)) != -1 && !isCancelled()) {
				fileOutput.write(buffer, 0, bufferLength);

				bytesIn++;
				bytesInThreshold++;
				if (updateDelta >= UPDATE_INTERVAL) {
					double percent = (bytesIn / (double)EXPECTED_SIZE_IN_BYTES) * 100;
					double speed = calculate(updateDelta, bytesInThreshold);

					publishProgress(percent, speed);

					// Reset
					updateStart = System.currentTimeMillis();
					bytesInThreshold = 0;
				}
				updateDelta = System.currentTimeMillis() - updateStart;
			}

			fileOutput.close();

			downloadTime = (System.currentTimeMillis() - start);
			// Prevent AritchmeticException
			if (downloadTime == 0) {
				downloadTime = 1;
			}

		}
		catch (MalformedURLException e) {
			Log.w(TAG, "MalformedURLException " + e.getMessage());
		}
		catch (IOException e) {
			Log.w(TAG, "IOException " + e.getMessage());
		}
		finally {
			try {
				if (stream != null) {
					stream.close();
				}
			}
			catch (Exception e) {
				Log.w(TAG, "Exception " + e.getMessage());
			}
		}

		return calculate(downloadTime, bytesIn);
	}

	@Override
	protected void onProgressUpdate(Double... progress) {
		double percent = progress[0];
		double speed = progress[1];

		updateProgress(percent, speed);
	}

	@Override
	protected void onPostExecute(Double speed) {
		updateProgress(100, speed);
		btnStart.setText(R.string.mainbtn_down_comp);
		mainAct.onDownloadComplete();
	}

	@Override
	protected void updateProgress(double percent, double speed) {
		mProgressBar.setProgress((int)percent);
		mTxtProgress.setText(String.format("%d", (int)percent) + "%");

		mTxtDownSpeed.setText(mDecimalFormater.format(speed) + KBIT_SEC);

		mainAct.setPointer(speed);
	}
}
